{-# LANGUAGE CPP, TemplateHaskell #-}
-----------------------------------------------------------------------------
--
-- Module      :  Main
-- Copyright   :
-- License     :  AllRightsReserved
--
-- Maintainer  :
-- Stability   :
-- Portability :
--
-- |
--
-----------------------------------------------------------------------------

module Main (
    main
) where

primes :: [Integer]
primes = 2 : filter isPrime [3,5..]

isPrime :: Integer -> Bool
isPrime n = all (\x -> n `rem` x /= 0) candidates
  where candidates = takeWhile (\x -> x <= threshold) primes
        threshold = floor . sqrt . fromIntegral $ n

getPrimeDelimeters :: Integer -> [Integer]
getPrimeDelimeters n = if isPrime n
                        then [1]
                        else 1:(populatePrimes n (filter (\x -> n `rem` x == 0) candidates))
  where candidates = takeWhile (\x -> x <= threshold) primes
        threshold = 1 + (floor . sqrt . fromIntegral $ n)

timesPrime :: Integer -> Integer -> Integer
timesPrime n p = if n `rem` p /= 0
                    then 0
                    else 1 + timesPrime (n `div` p) p

populateElement :: Integer -> Integer -> [Integer]
populateElement n t = if t == 0
                        then []
                        else n:populateElement n (t-1)
populatePrimes :: Integer -> [Integer] -> [Integer]
populatePrimes n [] = []
populatePrimes n (x:xs) = (populateElement x (timesPrime n x))++(populatePrimes n xs)

------------------------------------------------------------------------------
------------------------------------------------------------------------------

getDelimeters :: Integer -> [Integer]
getDelimeters n = filter (\x -> n `rem` x == 0) (takeWhile (\x -> x <= threshold) [1,2..])
    where threshold = n `div` 2

isIdeal :: Integer -> Bool
isIdeal n = sum(getDelimeters n)==n

ideals :: [Integer]
ideals = filter isIdeal [6,7..]


main = do
    print $ take 4 ideals
